<?php
/**
 * Created by Administrator
 * User: longli
 * VX: isa1589518286
 * Date: 2020/08/12
 * Time: 10:52
 * @link http://www.lmterp.cn
 */

namespace app\common\service\platform;


use app\common\library\Tools;
use app\common\model\AccountSyncLog;
use app\common\model\OrdersTemp;
use app\common\service\channel\BaseChannel;
use app\common\service\orders\OrderService;
use Shopee\Client;
use think\facade\Log;

/**
 * 虾皮接口服务
 * PDF https://cdngarenanow-a.akamaihd.net/shopee/seller/seller_cms/7b843967e3c067a000d8bc2ffc73e2db/[TW][Open%20API]API%E4%B8%B2%E6%8E%A5%E8%AA%AA%E6%98%8E%E4%BA%8B%E9%A0%85%20(2019_9)_new.pdf
 * Class ShopeeService
 * @package app\common\service\shopee
 * @link https://open.shopee.com/documents
 */
class ShopeeService extends BasePlatformService
{
    public static $tokenField = [
        'required' => [ // 必填字段
            [
                'type' => 'text',
                'name' => 'secret',
                'field' => 'secret',
            ],
            [
                'type' => 'text',
                'name' => 'shopid',
                'field' => 'shopid',
            ],
            [
                'type' => 'text',
                'name' => 'partner_id',
                'field' => 'partner_id',
            ],
        ],
        'option' => [ // 可选字段
        ],
    ];
    /**
     * 获取订单列表
     * @param array $params 参数配置，默认抓取当天订单
     * <ul>
     * <li>string|int start_date 开始抓取时间，默认为今天</li>
     * <li>string|int end_date 结束抓取时间，默认为当前时间</li>
     * <li>int status 订单状态，默认为 READY_TO_SHIP</li>
     * </ul>
     * @param bool $replace 是否替换原有的订单，默认不替换
     * @date 2020/08/15
     * @author longli
     * @link https://partner.shopeemobile.com/api/v1/orders/basics
     */
    public function getOrderList($params = [], $replace = false)
    {
        Log::info(sprintf("shopee 批量同步账号【%d】订单，请求参数: 【%s】", $this->getAccountId(), json_encode($params)));
        $startSyncTime = time();
        $client = $this->getClient();
        $limit = !empty($params['page_size']) && $params['page_size'] < 101
                ? $params['page_size']
                : 100;
        $from = !empty($params['start_date'])
                ? (!is_numeric($params['start_date']) ? strtotime($params['start_date'])
                : $params['start_date']) : strtotime("-1day");
        $status = !empty($params['status'])
                ? $params['status']
                : 'READY_TO_SHIP';
        $to = !empty($params['end_date'])
                ? (!is_numeric($params['end_date']) ? strtotime($params['end_date'])
                : $params['end_date']) : time();
        $offset = 0;
        do
        {
            $response = $client->order->getOrdersList([
                "create_time_from" => $from,
                "create_time_to" => $to,
                "pagination_offset" => $offset * $limit,
                "pagination_entries_per_page" => $limit,
                "order_status" => $status,
            ]);
            $data = $response->getData();
            if(!isset($data['orders']))
            {
                // 请求出错
                Log::info(sprintf("shopee 获取订单异常, 账号:【%d】, 提示信息:【%s】", $this->getAccountId(), json_encode($data)));
                break;
            }
            $orderDetail = $client->order->getOrderDetails(["ordersn_list" => array_column($data['orders'], 'ordersn')])->getData();
            if(!isset($orderDetail['orders']))
            {
                // 请求出错
                Log::info(sprintf("shopee 获取订单详情异常, 账号:【%d】, 提示信息:【%s】", $this->getAccountId(), json_encode($data)));
                break;
            }
            $orderNo = array_column($orderDetail['orders'], 'ordersn');
            // 获取面单和追踪号
            $labels = $this->getLabel($orderNo);
            foreach($orderDetail['orders'] as $order)
            {
                $order['label_url'] = $labels[$order['ordersn']]['label_url'];
                $this->pushOrderToTemp($order['ordersn'], $order, $replace);
            }
            $offset++;
        }while($data['more']);
        // 添加同步订单日志
        AccountSyncLog::addLog($this->getAccountId(), $startSyncTime, time(), $params);
    }

    /**
     * 获取面单和追踪号
     * @param string[]|string 平台订单号
     * @return array
     * @date 2020/08/28
     * @author longli
     */
    public function getLabel($orderNo)
    {
        $client = $this->getClient();
        if(!is_array($orderNo)) $orderNo = [$orderNo];
        $labels = $client->logistics->getAirwayBill([
            "ordersn_list" => $orderNo,
        ])->getData();
        $ret = [];
        // 处理成功
        if(!empty($labels['result']['airway_bills']))
        {
            foreach($labels['result']['airway_bills'] as $bills)
            {
                $url = $bills['airway_bill'];
                $response = Tools::curlGet($url);
                // 保存面单到本地服务器
                if($response['status']) $url = BaseChannel::saveLabel($response['data']);
                $ret[$bills['ordersn']] = [
                    'label_url' => $url,
                    'label_error' => '',
                ];
            }
        }
        // 处理失败
        if(!empty($labels['result']['errors']))
        {
            foreach($labels['result']['errors'] as $error)
            {
                $ret[$error['ordersn']] = [
                    'label_url' => '',
                    'label_error' => $error['error_description'],
                ];
                Log::info(sprintf("shopee 获取面单失败，平台订单号【%s】，错误信息：【%s】", $error['ordersn'], $error['error_description']));
            }
        }
        return $ret;
    }

    /**
     * 获取操作 shopee 客户端
     * @return Client
     * @date 2020/08/27
     * @author longli
     */
    public function getClient()
    {
        $account = $this->getAccount();
        return new Client([
            'secret' => $account->token->secret,
            'partner_id' => intval($account->token->partner_id),
            'shopid' => intval($account->token->shopid),
        ]);
    }

    /**
     * @inheritDoc
     */
    public function syncOrder(OrdersTemp $ordersTemp)
    {
        $data = $ordersTemp->order_info;
        $info = [];
        foreach($data['items'] as $item)
        {
            $info[] = [
                "item_id"       => $item['item_id'], // 商品 id
                "qty"           => $item['variation_quantity_purchased'], // 数量
                "return_qty"    => 0, // 取消数量
                "price"         => $item['variation_original_price'], // 售价
                "platform_sku"  => $item['item_sku'], // sku
                "image_url"         => null, // 图片
                "name"          => $item['item_name'], // 产品名称
                'url'           => null, // 商品在线地址
            ];
        }

        $platform = $this->getAccountById($ordersTemp->account_id)->platform;
        $address = & $data['recipient_address'];
        $order = [
            "order_no"                  => $ordersTemp->order_no,
            "account_id"                => $ordersTemp->account_id,
            "platform_name"             => $platform->name, // 平台名称
            "order_platform_status"     => $data['order_status'], // 订单在平台的状态
            "buyer_gender"              => null, // 客户性别
            "buyer_company"             => null, // 客户公司
            'consignee'                 => $address['name'], // 收件人
            "buyer_first_name"          => '', // 客户名称
            "buyer_last_name"           => '', // 客户名称
            "buyer_phone"               => $address["phone"], // 电话
            "buyer_country"             => '', // 国家
            "buyer_country_code"        => $data['country'], // 国家编码
            'buyer_province'            => $address['state'], // 买家所在省，州
            "buyer_district"            => $address['district'], // 区
            "buyer_city"                => $address['city'], // 城市
            "buyer_post_code"           => $address['zipcode'], // 邮编
            "buyer_address_1"           => $address['full_address'], // 买家收货地址1
            "buyer_address_2"           => '', // 买家收货地址2
            "buyer_email"               => '', // 买家邮箱
            "shipping_price"            => $data['estimated_shipping_fee'], // 订单运费
            "order_source_create_time"  => $this->parseTimeToDate($data['create_time']), // 订单在平台生成的时间
            "latest_delivery_time"      => null, // 最迟发货时间
            "payment_method"            => $data['payment_method'], // 支付方式
            "order_price"               => $data['escrow_amount'], // 订单金额
            "total_price"               => $data['total_amount'], // 订单总金额
            "order_pay_time"            => $data['pay_time'] ? $this->parseTimeToDate($data['pay_time']) : null, // 订单支付时间
            "currency"                  => $data['currency'], // 币种
            "invoice_type"          => '', // 发票种类
            "invoice_title"             => '', // 发票抬头
            "invoice_detail"            => '', // 发票详情
            "track_num"                 => $data['tracking_no'], // 追踪号
            "track_num_time"            => !empty($data['tracking_no']) ? Tools::now() : null, // 更新追踪号时间
            "label_url"                 => $data['label_url'], // 面单
            "platform_remark"           => $data['message_to_seller'], // 买家备注信息
            "order_detail" => $info,
        ];
        return OrderService::getInstance()->addOrder($order);
    }
}